package com.north.light.libpicblur;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Path;
import android.graphics.RectF;
import android.renderscript.Allocation;
import android.renderscript.Element;
import android.renderscript.RenderScript;
import android.renderscript.ScriptIntrinsicBlur;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;

import androidx.annotation.Nullable;

/**
 * FileName: LibPicBlurCusView
 * Author: lzt
 * Date: 2022/11/22 16:04
 * 自定义毛玻璃view--代码控制模糊次数
 */
public class LibPicBlurCusView extends androidx.appcompat.widget.AppCompatImageView implements LibPicBlurCusApi {
    private static final String TAG = LibPicBlurCusView.class.getSimpleName();
    //毛玻璃对象布局
    private View mParentBlurView;
    // 图片缩放比例(即模糊度)
    private static final float BITMAP_SCALE = 1f;

    public LibPicBlurCusView(Context context) {
        super(context);
    }

    public LibPicBlurCusView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public LibPicBlurCusView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    protected int dp2px(int dpValue) {
        return (int) getContext().getResources().getDisplayMetrics().density * dpValue;
    }

    /**
     * 开始模糊
     */
    @Override
    public void startBlur(View parentView) {
        startBlur(parentView, 22f);
    }

    @Override
    public void startBlur(View parentView, float blurRadius) {
        startBlur(parentView, blurRadius, 0);
    }

    @Override
    public void startBlur(View parentView, float blurRadius, int cornerRadius) {
        this.mParentBlurView = parentView;
        if (this.mParentBlurView == null) {
            setImageBitmap(null);
            return;
        }
        postDelayed(new Runnable() {
            @Override
            public void run() {
                try {
                    start(blurRadius, cornerRadius);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }, 10);
    }

    private void recycleBitmap(Bitmap bitmap) {
        try {
            if (bitmap != null && !bitmap.isRecycled()) {
                bitmap.recycle();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * @param context   上下文对象
     * @param srcBitmap 需要模糊的图片
     * @return 模糊处理后的Bitmap
     */
    public Bitmap blurBitmap(Context context, Bitmap srcBitmap, float blurRadius) {
        // 计算图片缩小后的长宽
        int width = Math.round(srcBitmap.getWidth() * BITMAP_SCALE);
        int height = Math.round(srcBitmap.getHeight() * BITMAP_SCALE);
        // 将缩小后的图片做为预渲染的图片
        Bitmap inputBitmap = Bitmap.createScaledBitmap(srcBitmap, width, height, false);
        // 创建一张渲染后的输出图片
        Bitmap outputBitmap = Bitmap.createBitmap(inputBitmap);
        // 创建RenderScript内核对象
        RenderScript rs = RenderScript.create(context);
        // 创建一个模糊效果的RenderScript的工具对象
        ScriptIntrinsicBlur blurScript = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs));
        // 由于RenderScript并没有使用VM来分配内存,所以需要使用Allocation类来创建和分配内存空间
        // 创建Allocation对象的时候其实内存是空的,需要使用copyTo()将数据填充进去
        Allocation tmpIn = Allocation.createFromBitmap(rs, inputBitmap);
        Allocation tmpOut = Allocation.createFromBitmap(rs, outputBitmap);
        // 设置渲染的模糊程度, 25f是最大模糊度
        float bRadius = Math.min(Math.max(1, blurRadius), 25);
        blurScript.setRadius(bRadius);
        // 设置blurScript对象的输入内存
        blurScript.setInput(tmpIn);
        // 将输出数据保存到输出内存中
        blurScript.forEach(tmpOut);
        // 将数据填充到Allocation中
        tmpOut.copyTo(outputBitmap);
        rs.destroy();
        recycleBitmap(inputBitmap);
        return outputBitmap;
    }

    private void start(float blurRadius, int cornerRadius) throws Exception {
        //开始毛玻璃
        //父布局屏幕中的位置
        final int[] parentLocations = new int[2];
        mParentBlurView.getLocationOnScreen(parentLocations);
        //子布局屏幕中的位置
        final int[] childLocations = new int[2];
        getLocationOnScreen(childLocations);
        int cropWidth = getMeasuredWidth();
        int cropHeight = getMeasuredHeight();
        int left = childLocations[0] - parentLocations[0];
        int top = childLocations[1] - parentLocations[1];
        final int right = cropWidth;
        final int bottom = cropHeight;
        //获取控件bitmap
        LibPicBlurViewShotUtils.viewSnapShot(this.mParentBlurView, new LibPicBlurViewShotUtils.ViewSnapListener() {
            @Override
            public void success(Bitmap bitmap) {
                //缩放bitmap
                try {
                    Log.d(TAG, "success");
                    Bitmap canvasBitmap = Bitmap.createBitmap(cropWidth, cropHeight, Bitmap.Config.ARGB_8888);
                    Canvas canvas = new Canvas(canvasBitmap);

                    //四周圆角
                    if (cornerRadius > 0) {
                        Path mPath = new Path();
                        RectF canvasRectF = new RectF(0, 0, cropWidth, cropHeight);
                        mPath.addRoundRect(canvasRectF, dp2px(cornerRadius), dp2px(cornerRadius), Path.Direction.CW);
                        canvas.clipPath(mPath);
                    }

                    setImageBitmap(canvasBitmap);
                    Bitmap trainBitmap = Bitmap.createBitmap(bitmap, left, top, right, bottom);
                    Bitmap blurBitmap = blurBitmap(getContext(), trainBitmap, blurRadius);
                    canvas.drawBitmap(blurBitmap, 0, 0, null);
                    //释放相关对象
                    recycleBitmap(trainBitmap);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void failed(String message) {
                Log.d(TAG, "failed");
            }
        });
    }


}
